
// 立即执行函数 做区域划分
(() => {
    // 基本数据类型：number、string、boolean、undefined、null、symbol、void
    // 对象类型：class、object、array、function

    // ======================= 基本数据类型 ===================
    const number: number = 123
    const String = '1907A'
    const boolean = false;
    const Undefined: undefined = undefined
    const Null: null = null
    // es6
    const symbol: symbol = Symbol('a')
    const fun: () => void = () => { }


    // ======================== 对象类型 ======================
    class user {
        constructor() { }
        init() {
            console.log('触发')
        }
    }

    const newUser = new user();

    console.log(newUser.init())

    // ====================== object =========================
    const obj: { name: string, age: number, getName: (a: boolean | string) => string } = {
        name: '张三',
        age: 13,
        getName: (a) => '张三'
    }

    obj.getName('123')

    // ====================== array ============================
    const arr: (number | string)[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, '10']

    const objarr: { name: string, age: number }[] = [{ name: '张三', age: 12 }]

    // ==================== function ==============
    const getUserName = (name: string) => {
        console.log('getUserName')
        return 'name'
    }

    getUserName('张三')

    // ================ 类型注解  类型推论 ================
    // 类型注解：告知ts  变量的数据类型 
    const newString: string = '八维'


    // 类型推论：ts 会根据 变量的值 判断数据类型
    // 其中 null 和 undefined 会被ts 推论成any
    // any 任意类型
    let newNumber = null

    let newUndefined = undefined;


    // TS 推论 函数返回字符串类型
    const func = () => {
        return '1907a'
    }

    func()

    // 如果函数由参数 必须要给参数添加类型  ts无法推论参数的数据类型
    const newFunc = (a: number, b: number) => {
        return a + b
    }

    newFunc(1, 2)

    // ====================== 函数 ========================
    // es5
    function funEs5(str1: string, str2: string): string {
        return str1 + str2
    }

    console.log(funEs5('上海', '八维'))

    // es6 自动推论函数没有反回值 void
    const funEs6 = () => { }

    funEs6()

    // es6  自动推论返回值为string
    const funEs6String = () => {
        return '1907A'
    }

    // es6  第一种方式 注解 返回值类型
    // const newFunEs6String: () => string = () => {
    //     return '1907A'
    // }

    // 第二种方式 注解 返回值类型
    const newFunEs6String = (): string => {
        return '1907A'
    }

    // 注解 返回值类型 object
    const funEs6Object: () => { name: string, age: number } = () => {
        return {
            name: '张三',
            age: 14
        }
    }

    // 注解 返回值类型 array
    const funEs6Array = (): { name: string, age: number }[] => {
        return [
            {
                name: '张三',
                age: 14
            },
            {
                name: '李四',
                age: 14
            }
        ]
    }

    // 规定函数 没有返回值: void
    const funEs6Void = (): void => { }

    // 规定函数 无线循环
    const funEs6Never = (): never => {
        // 无线循环
        while (true) { }
    }

    // 规定函数参数类型  第一中
    const funEs6s = (name: string, age: number): string => {
        return `姓名:${name};年龄:${age}`
    }

    console.log(funEs6s('张三', 14))

    // 规定函数参数类型  第二中
    const funEs6s2: (name: string, age: number) => string = (name, age) => {
        return `姓名:${name};年龄:${age}`
    }

    // ===================== 类 , 类继承 ================
    class person {
        // 规定 在当前类或者是被继承的类中使用
        protected age: number = 14
        // 规定 只能在当前类中使用
        private name: string = '张三'
        // 规定 在类 内外都可以使用
        public getName: () => { name: string, age: number } = () => {
            return {
                name: this.name,
                age: this.age
            }
        }
    }

    const newPerson = new person()

    console.log(newPerson.getName()) // { name: '张三', age: 14 }
    // console.log(newPerson.name) // 属性“name”为私有属性，只能在类“person”中访问。
    // console.log(newPerson.age) // 属性“age”受保护，只能在类“person”及其子类中访问。

    // 继承
    class person1 extends person {
        public getInfo: () => number = () => {
            // console.log(this.name) // 属性“name”为私有属性，只能在类“person”中访问
            return this.age
        }
    }

    const newPerson1 = new person1()

    // ================= 数组、元组====================
    // 注解为字符串的数组
    const strArr: string[] = ["张三", "李四", "王五", "赵六"]

    const numArr: number[] = [1, 2, 3, 4, 5]

    // 数组内容为混合类型 => 元组
    const allArr:(string | number | boolean | null | undefined | (() => void) | arrType )[] = ['淫东', 15, false, () => {}, '张三', () => {}, null, undefined, {name: '张三', age: 16, sex:'男'}]


    // 给对象 添加类型别名
    type arrType = {
        name: string,
        age: number,
        sex: string
    }

    // ====================== 类型别名 、 接口 ==============================
    const userInfo = {
        name: "张三",
        age: 14,
        sex: false,
        info: '的把握奥迪爱的安排大王地爬到阿发啊',
        id: '345617892343342',
        height: 170,
        weight: 100,
        getInfo: () => {
            return {
                name: "张三",
                age: 14,
                sex: false,
            }
        }
    }
    
    const userInfo1 = {
        name: "淫东",
        age: 19,
        sex: false,
        info: null,
        id: '45672834924',
        height: '不详',
        weight: undefined,
        getInfo: () => {
            return {
                name: "淫东",
                age: 19,
                sex: false,
            }
        }
    }

    const userInfoArr:userInfoType[] = [userInfo, userInfo1];

    // 接口 interface 描述对象类型
    interface userInfoType {
        name: string,
        age: number,
        sex: boolean,
        info: string | null,
        id: string,
        height: string | number,
        weight: number | undefined,
        getInfo: () => {
            name: string,
            age: number,
            sex: boolean
        }
    }

    // 联合 类型接口  联合：类型不一致
    interface type {
        name: string,
        age: number,
        hobby: string | string[] | (() => string[])
    }

    const user1:type = {
        name: "小红",
        age: 14, 
        hobby:"抽烟"
    }

    const user2:type = {
        name: '小明',
        age: 17,
        hobby: ["抽烟", "喝酒"]
    }

    const user3:type = {
        name: '小东',
        age: 20,
        hobby: () => {
            return ["抽烟","喝酒","烫头"]
        }
    }
})()